package com.zhl.configurer;

import org.apache.shiro.cache.ehcache.EhCacheManager;
import org.apache.shiro.session.mgt.SessionManager;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.mgt.WebSecurityManager;
import org.apache.shiro.web.servlet.SimpleCookie;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.servlet.Filter;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * @Author zhl
 * @Description
 */
@Configuration
public class ShiroConf {


    //注入shiro过滤器
    @Bean("shiroFilterFactoryBean")
    public ShiroFilterFactoryBean shiroFilter(WebSecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        // 必须设置 SecurityManager
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        shiroFilterFactoryBean.setLoginUrl("/admin/login");  // 如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面
        shiroFilterFactoryBean.setSuccessUrl("/admin/index");// 登录成功后要跳转的链接
        shiroFilterFactoryBean.setUnauthorizedUrl("/unauthorized");//设置无权限跳转页面

        //roles[user,admin,root]默认是and的关系,使用自己定义的filter,改成or的关系
        Map<String, Filter> filters = new LinkedHashMap<>();
        filters.put("roles",roleOrFilter());
        shiroFilterFactoryBean.setFilters(filters);


        Map<String, String> chains = new LinkedHashMap<>();
        chains.put("/logout", "logout");//登出
        chains.put("/login", "anon");//anon表示可以匿名访问
        chains.put("/pagelogin", "anon");//anon表示可以匿名访问
        //对PermissionAction.class 中的url进行权限控制

//        chains.put("/admin/article", "roles[user,admin,root]");//这个设置方法原本是需要每个参数都满足才算通过
        chains.put("/menu/getmenu", "roles[user,admin,root]");//
        chains.put("/admin/article", "roles[user,admin,root]");//使用自定义的filter后,需要user,admin,root中的一个角色就可以
        chains.put("/admin/about", "roles[user,root,admin]");
        chains.put("/admin/apply", "roles[user,root,admin]");
        chains.put("/admin/context", "roles[user,root,admin]");
        chains.put("/admin/message", "roles[user,root,admin]");
        chains.put("/admin/modify", "roles[user,root,admin]");
        chains.put("/admin/publish", "roles[user,root,admin]");
        chains.put("/admin/link", "roles[root,admin]");
        chains.put("/admin/music", "roles[root,admin]");
//        chains.put("/admin/music", "perms[user:query]");
        chains.put("/admin/index", "roles[user,root,admin]");
        chains.put("/admin/user", "roles[admin]");
        chains.put("/admin/function", "roles[admin]");
        chains.put("/admin/role", "roles[admin]");
        chains.put("/api/**", "anon");
        //chains.put("/**", "authc");
//        chains.put("/**", "user");

        chains.put("/css/**", "anon");
        chains.put("/fonts/**", "anon");
        chains.put("/images/**", "anon");
        chains.put("/img/**", "anon");
        chains.put("/js/**", "anon");
        chains.put("/**", "anon");
        chains.put("**/swagger-resources/**", "anon");

        shiroFilterFactoryBean.setFilterChainDefinitionMap(chains);

        return shiroFilterFactoryBean;
    }

    //重写的filter,实现权限的或关系
    @Bean("ZhlAuthorizationFilter")
    public ZhlAuthorizationFilter roleOrFilter() {
        return new ZhlAuthorizationFilter();
    }


    //安全管理器
    @Bean
    public WebSecurityManager securityManager() {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        // 设置realm.
        securityManager.setRealm(shiroRealm());
        securityManager.setCacheManager(cacheManager());
//        securityManager.setSessionManager(sessionManager());
        return securityManager;
    }

    //会话管理器
    @Bean
    public SessionManager sessionManager() {
        DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
        sessionManager.setSessionIdUrlRewritingEnabled(false);
        sessionManager.setGlobalSessionTimeout(1 * 60 * 60 * 1000);
        sessionManager.setDeleteInvalidSessions(true);
        sessionManager.setSessionIdCookie(simpleCookie());
        return sessionManager;
    }

    //Realm，里面是自己实现的认证和授权业务逻辑
    @Bean
    public ShiroRealm shiroRealm() {
        ShiroRealm shiroRealm = new ShiroRealm();
//        shiroRealm.setCacheManager(cacheManager());
//        shiroRealm.setCredentialsMatcher(hashedCredentialsMatcher());
        return shiroRealm;
    }

    //缓存管理
    @Bean
    public EhCacheManager cacheManager() {
        EhCacheManager cacheManager = new EhCacheManager();
        cacheManager.setCacheManagerConfigFile("classpath:ehcache.xml");
        return cacheManager;
    }

    //密码管理
   /* @Bean
    public HashedCredentialsMatcher hashedCredentialsMatcher() {
        HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();
        credentialsMatcher.setHashAlgorithmName("md5"); //散列算法使用md5
        credentialsMatcher.setHashIterations(2);        //散列次数，2表示md5加密两次
        credentialsMatcher.setStoredCredentialsHexEncoded(true);//启用十六进制存储
        return credentialsMatcher;
    }*/

    //cookie管理
    @Bean
    public SimpleCookie simpleCookie() {
        SimpleCookie cookie = new SimpleCookie("sessionId");
        cookie.setHttpOnly(true);
        cookie.setMaxAge(1 * 60 * 60);
        return cookie;
    }


}
